var saveButton = $('a.save-button');

var LocalityModel = function(id, name) {

	var self = this;

	self.id = id;

	self.locality = name;

};

var ClusterModel = function(id, name, locality) {

	var self = this;

	self.id = id;

	self.cluster = name;

	self.locality = locality;
};

var DistrictModel = function(localities, clusters, districts) {

	var self = this;

	self.ids = [];

	self.localities = null;

	self.initializeLocalities = function() {
		var l = [];

		for (i = 0; i < localities.length; i++) {
			var locality = localities[i];
			var localityModel = new LocalityModel(locality.Id, locality.Locality);
			l.push(localityModel);
		}

		self.localities = ko.observableArray(l);		
	};

	self.initializeLocalities();

	self.clusters = null;

	self.initializeClusters = function() {
		var c = [];

		for (i = 0; i < clusters.length; i++) {
			var cluster = clusters[i];
			var clusterModel = new ClusterModel(cluster.Id, cluster.Cluster, cluster.LocalityId);
			c.push(clusterModel);		
		}

		self.clusters = ko.observableArray(c);
	};

	self.initializeClusters();

	self.isValid = function() {
		var valid = true;
		var items = ko.toJS(self.districts);
		
		if (items != undefined) {
			if (items.length != undefined) {
				for (i = 0; i < items.length; i++) {
					var item = items[i];
					valid = valid && ($.trim(item.District) != '');
					if (!valid) break;
					else {
						valid = valid && (item.Locality != '') && (item.Locality != 'Choose one...');
						if (!valid) break;
					}
				}	
			}	
		}
		
		return valid;
	};

	self.districts = ko.observableArray(ko.utils.arrayMap(districts, function(district) {
		self.ids.push(district.Id);

		var viewModel = { 
							Id : district.Id, 
							Locality : district.LocalityId,
							Cluster : district.ClusterId,
							District : district.District,
							Description : district.Description,
							RowState : 'unchanged'
						};

		viewModel.Locality = ko.observable(district.LocalityId).extend( { modelUpdated : viewModel, validator: { 'saveButton': saveButton, references: ko.toJS(self.localities), referenceKey: 'id', saveButtonEnable: function() { return self.isValid(); } } } );
		viewModel.Cluster = ko.observable(district.ClusterId).extend( { modelUpdated : viewModel } );
		viewModel.District = ko.observable(district.District).extend( { modelUpdated : viewModel, validator: { 'saveButton': saveButton, saveButtonEnable: function() { return self.isValid(); } } } );
		viewModel.Description = ko.observable(district.Description).extend( { modelUpdated : viewModel } );
		viewModel.clusters = ko.computed(function() {
			var cl = ko.toJS(self.clusters);
			var dataSource = [];
			var selectedLocality = '';

			try {
				selectedLocality = viewModel.Locality();
			}
			catch (ex) {

			}

			$.each(cl, function(index) {
				var c = this;
				if (dataSource.length <= 0) dataSource.push( { 'id' : 0, 'locality' : selectedLocality, cluster: 'N/A' } );
				if (c.locality == selectedLocality) dataSource.push(c);
			});

			return dataSource;
		});

		return viewModel;
	}));

	self.deletedItems = [];

	self.acceptChanges = function(viewUpdates) {
		ko.utils.arrayForEach(self.districts(), function(district) {
			district.RowState = 'unchanged';

			if (viewUpdates != null &&
				viewUpdates != undefined) {
				for (i = 0; i < viewUpdates.length; i++) {
					var viewUpdate = viewUpdates[i];
					if (district.Id == viewUpdate.Id) {
						district.Id = viewUpdate.GeneratedId;
						break;
					}
				}
			}
		});
	};

	self.add = function() {
		var id = 1;

		if (self.ids.length > 0) {
			var max = Math.max.apply(Math, self.ids);
			id = max + 1;
		}

		self.ids.push(id);
		
		var viewModel = {
							Id : id,
							Locality: 0,
							Cluster: 0,
							District: '',
							Description: '',
							RowState: 'added'
						};

		viewModel.Locality = ko.observable(0).extend( { modelUpdated : viewModel, validator: { 'saveButton': saveButton, references: ko.toJS(self.localities), referenceKey: 'id', saveButtonEnable: function() { return self.isValid(); } } } );
		viewModel.Cluster = ko.observable(0).extend( { modelUpdated : viewModel } );
		viewModel.District = ko.observable('').extend( { modelUpdated : viewModel, validator: { 'saveButton': saveButton, saveButtonEnable: function() { return self.isValid(); } } } );
		viewModel.Description = ko.observable('').extend( { modelUpdated : viewModel } );
		viewModel.clusters = ko.computed(function() {
			var cl = ko.toJS(self.clusters);
			var dataSource = [];
			var selectedLocality = '';

			try {
				selectedLocality = viewModel.Locality();
			}
			catch (ex) {

			}

			$.each(cl, function(index) {
				var c = this;
				if (dataSource.length <= 0) dataSource.push( { 'id' : 0, 'locality' : selectedLocality, cluster: 'N/A' } );
				if (c.locality == selectedLocality) dataSource.push(c);
			});

			return dataSource;
		});

		self.districts.push(viewModel);

		setRemoveDistrictToolTips();

		var table = $('.districts-table');
		table.floatThead('reflow');

		if (!saveButton.hasClass('disabled')) saveButton.addClass('disabled');
		
		var rowLocalityInput = $('tr[data-id="' + id + '"] td .form-group select.locality-input');
		rowLocalityInput.focus();
	};

	self.getChanges = function() {
		var updates = [];
		var items = ko.toJS(self.districts);

		for (i = 0; i < items.length; i++) {
			var item = items[i];
			if (item.RowState != 'unchanged') updates.push( { Id: item.Id, Locality: item.Locality, Cluster: item.Cluster, District: item.District, Description: item.Description, RowState: item.RowState } );
		}

		for (i = 0; i < self.deletedItems.length; i++) {
			var item = self.deletedItems[i];
			updates.push( { Id: item.Id, Locality: 0, Cluster: 0, District: '', Description: '', RowState: 'deleted' } );	
		}

		return updates;
	};

	self.remove = function(district) {
		unsetRemoveDistrictToolTips();
		
		if (district.RowState != 'added') {
			district.RowState = 'deleted';
			self.deletedItems.push(district);
		}
		
		self.districts.remove(district);
		setRemoveDistrictToolTips();

		if (self.isValid())  saveButton.removeClass('disabled');
		else {
			if (!saveButton.hasClass('disabled')) saveButton.addClass('disabled');
		}
	};

	self.save = function() {
		if (saveButton.hasClass('disabled')) return;
		else saveButton.addClass('disabled');

		saveButton.button('loading');

		var updates = self.getChanges();

		var withUpdates = false;

		if (updates != null) withUpdates = (updates.length > 0);

		if (withUpdates) {
			$.ajax({
			    type: 'POST',
			    url: app.baseUrl() + 'index.php/references/update',
			    data: { 'data' : JSON.stringify(updates) },
			    dataType: 'json'
			}).done(function(response) {
				if (response != null) {
					if (response.saved) {
						var viewUpdates = null;

						if (response.viewUpdates != null &&
							response.viewUpdates != undefined) viewUpdates = response.viewUpdates;
						
						self.acceptChanges(viewUpdates);
						
						infoGritter({
							title: 'Record Update',
							text: 'Applied updates has been saved.'
						});
					}
					else {
						var message = 'Applied updates were not saved into the database.';

						if (response.message != undefined &&
							response.message != null) {
							if (response.message.trim() != '') message = response.message;
						}

						warningGritter({
							title: 'Record Update',
							text: message
						});
					}
				}
			}).fail(function(response) {
				try {
					console.error(response);
				}
				catch (ex) {

				}

				errorGritter({
					title: 'Oooops',
					text: 'Something went wrong while applying the updates into the server.'
				});
			}).always(function() {
				saveButton.removeClass('disabled');
				saveButton.button('reset');
			});
		}
		else {
			saveButton.removeClass('disabled');
			saveButton.button('reset');
		}
	};

};

var setRemoveDistrictToolTips = function() {
	unsetRemoveDistrictToolTips();
	var removeLinks = $('a.remove-record');
	removeLinks.tooltip( { 
			'title' : 'Remove current line-item from the list.',
			'trigger' : 'hover',
			'container' : 'body' 
		} 
	);
};

var unsetRemoveDistrictToolTips = function() {
	var removeLinks = $('a.remove-record');
	removeLinks.tooltip('destroy');
};

$(document).ready(function() {
	var displaySection = $('.table-container');
	app.loader({ container: displaySection });

	$.post(app.baseUrl() + 'index.php/references/localities').done(function(localityData) {
		var localities = null;

		try {
			localities = JSON.parse(localityData);
		}
		catch (ex) {

		}

		if (localities != null) {
			$.post(app.baseUrl() + 'index.php/references/clusters').done(function(clusterData) {
				var clusters = null;

				try {
					clusters = JSON.parse(clusterData);
				}
				catch (ex) {

				}

				if (clusters != null) {
					$.post(app.baseUrl() + 'index.php/references/districts').done(function(districtData) {
						var districts = null;

						try {
							districts = JSON.parse(districtData);
						}
						catch (ex) {

						}

						if (districts != null) {
							ko.applyBindings(new DistrictModel(localities, clusters, districts));
							setRemoveDistrictToolTips();

							var table = $('.districts-table');
							table.floatThead({
							    scrollContainer: function(refTable){
									return refTable.closest('.table-container');
								}
							});
						}
					}).fail(function(response) {
						try {
							console.error(response);
						}
						catch (ex) {

						}

						errorGritter({
							title: 'Oooops',
							text: 'Something went wrong while loading the data to be displayed. Please try again.'
						});
					}).always(function() {
						app.loader('hide');
					});
				}
			}).fail(function(response) {
				try {
					console.error(response);
				}
				catch (ex) {

				}

				errorGritter({
					title: 'Oooops',
					text: 'Something went wrong while loading some references. Please try again.'
				});

				app.loader('hide');
			}).always(function() {

			});
		}
	}).fail(function(response) {
		try {
			console.error(response);
		}
		catch (ex) {

		}

		errorGritter({
			title: 'Oooops',
			text: 'Something went wrong while loading some references. Please try again.'
		});

		app.loader('hide');
	}).always(function() {

	});
});

